package com.contory.ssn_lgnd.app.maingame;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;

import android.util.Log;

import com.contory.ssn_lgnd.app.comp.DrawPtr;
import com.contory.ssn_lgnd.app.comp.UpdatePtr;
import com.contory.ssn_lgnd.framework.Pool;
import com.contory.ssn_lgnd.framework.Pool.PoolObjectFactory;
import com.contory.ssn_lgnd.framework.gl.SpriteBatcher;

public class EnemyManager implements UpdatePtr, DrawPtr{
	//LinkedList<Enemy> enemyList;
	ArrayList<EnemyGroup> enemyGroupList;
	final Player player; 
	final ColisionManager cm; 
	final Fire fire; 
	final Random rand;
	final ParticleEffectGroup pEffectGroup;
	final TextureEffectGroup texEffectGroup;
	int AllocGroupID = 1;
	
	public EnemyManager(Player player, ColisionManager cm, Fire fire, Random rand, ParticleEffectGroup pEffectGroup, TextureEffectGroup texEffectGroup){
		enemyGroupList = new ArrayList<EnemyGroup>(20);
		this.player = player;
		this.cm = cm;
		this.fire = fire;
		this.rand = rand;
		this.pEffectGroup = pEffectGroup;
		this.texEffectGroup = texEffectGroup;
	}
	
	public EnemyGroup addEnemyGroup(){
		EnemyGroup enemyGroup = new EnemyGroup(player, cm, fire, rand, pEffectGroup, texEffectGroup, AllocGroupID++);
		enemyGroupList.add(enemyGroup);
		return enemyGroup;
	}
	
	public int getCurEnemyGroup(EnemyGroup obj){
		return enemyGroupList.indexOf(obj);
	}
	
	
	public Enemy addEnemy(float strX, float strY){
		if(enemyGroupList.size() == 0){
			try {
				throw new Exception("Fisrt add enemyGroup");
			} catch (Exception e) {
			  Log.d("ASSERT", e.getMessage());
			}
		}
		//Log.d("1", "1");
		Enemy enemy = enemyGroupList.get(enemyGroupList.size()-1).addEnemy(strX, strY); //getLast().addEnemy(strX, strY);
		return enemy;
	}
	
	public void removeEnemy(Enemy chdEnemy){
		int pos = searchEnemyGroup(chdEnemy.getGroupId(), enemyGroupList.size());
		if(pos <= -1){
			try {
				throw new Exception("Enemy chd don`t exist in Manager");
			} catch (Exception e) {
			  Log.d("ASSERT", e.getMessage());
			}
		}
		else{
			enemyGroupList.get(pos).removeEnemy(chdEnemy);
		}
	}
	
	public void removeGroup(EnemyGroup enemyGroup){
		enemyGroupList.remove(enemyGroup);
	}
	
	private int searchEnemyGroup(int groupId, int size){
		//invariant : always value exist in lis
		if(groupId <= -1)
			return -1;
		int mid = -1;
		int head = 0;
		int tail = size - 1;
		while(true){
			if(tail < head){
				mid = -1;
				break;
			}
			mid = (head + tail) / 2;
			if(groupId == enemyGroupList.get(mid).getGroupID())
				break;
			else if(groupId < enemyGroupList.get(mid).getGroupID()){
				tail = mid - 1;
			}
			else if(groupId > enemyGroupList.get(mid).getGroupID()){
				head = mid + 1;
			}
		}
		return mid;
	}
	
	public void clear(){
		enemyGroupList.clear();
	}
	
	public int getGroupSize(){
		return enemyGroupList.size();
	}

	@Override
	public void draw(SpriteBatcher batcher) {
		for(int i = 0; i < enemyGroupList.size(); i++){
			enemyGroupList.get(i).draw(batcher);
		}
	}
	
	@Override
	public void update(float deltaTime) {
		for(int i = 0; i < enemyGroupList.size(); i++){
			enemyGroupList.get(i).update(deltaTime);
			if(enemyGroupList.get(i).getEmptyBool()){
				enemyGroupList.remove(enemyGroupList.get(i));
			}
		}
	}
}
